﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Enterprise.Management.Common;
using Enterprise.Management.Data;
using System.Text;

namespace Enterprise.Management.Business
{
    public class UserBLL : BaseBLL
    {
        private const string RESET_PASSWORD_KEY = "K8R2OHFA8YTRQHWUFHAUEFQ";

        public UserBLL()
        { }

        public bool ValidateUser(string password, string hash)
        {
            return Security.CompareMD5(password, hash);
        }

        public DP_User GetUser(string username)
        {
            if (string.IsNullOrEmpty(username)) return null;
            return DataContext.DP_User.FirstOrDefault(m => m.User_Email == username && m.User_Status == (int)StatusType.Valid);
        }

        public DP_User GetUser(int id)
        {
            if (id <= 0) return null;
            return DataContext.DP_User.FirstOrDefault(m => m.User_ID == id && m.User_Status == (int)StatusType.Valid);
        }

        public bool UpdatePassword(int uid, string newPassword)
        {
            newPassword = Security.MD5(newPassword);
            var user = DataContext.DP_User.First(m => m.User_ID == uid);
            user.User_Pwd = newPassword;
            return Submit();
        }

        public bool SendResetMail(string email, string url)
        {
            var user = GetUser(email);
            string cryptograph = CreateForgetPasswordLink(user.User_ID);
            string address = url + "?m=" + cryptograph;
            StringBuilder body = new StringBuilder();
            body.AppendLine(string.Format("<div>用户 {0}：</div>", user.User_Name));
            body.AppendLine("<p>您的密码重置要求已经得到验证，请点击以下链接重置密码。</p>");
            body.AppendLine(string.Format("<p><a href='{0}'>{0}</a></p>", address));
            body.AppendLine("<p>重置后请使用默认密码登录，并尽快重新修改密码。</p>");


            string message;
            if (Email.Send(email, "重置密码邮件", body.ToString(), out message))
            {
                Log.Info(string.Format("邮箱{0}的重置密码邮件发送成功", email));
                return true;
            }
            else
            {
                Log.Info(string.Format("邮箱{0}的重置密码邮件发送失败，原因如下：{1}", email, message));
                return false;
            }
        }

        public bool VerifyForgetPasswordLink(string cryptograph, out int uid)
        {
            uid = 0;

            try
            {
                string[] content = cryptograph.Split('|');
                uid = Convert.ToInt32(content[0]);
                DateTime effectiveTime = new DateTime(Convert.ToInt64(content[1]));

                if (!Security.CompareMD5(GetResetPasswordString(uid, effectiveTime), HttpUtility.UrlDecode(content[2])))
                {
                    Log.Info(string.Format("the link is not correct. {0}", cryptograph));
                    return false;
                }

                if (effectiveTime < DateTime.Now)
                {
                    Log.Info(string.Format("effective time is expired. {0}", cryptograph));
                    return false;
                }

                return true;
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                return false;
            }
        }

        public bool ResetPassword(int uid)
        {
            var user = GetUser(uid);
            user.User_Pwd = Security.MD5(ManagementBLL.DEFAULT_USER_PASSWORD);
            return Submit();
        }

        private string CreateForgetPasswordLink(int uid)
        {
            DateTime effectiveTime = DateTime.Now.AddDays(1);

            return string.Format("{0}|{1}|{2}", uid, effectiveTime.Ticks, HttpUtility.UrlEncode(Security.MD5(GetResetPasswordString(uid, effectiveTime))));
        }

        private string GetResetPasswordString(int uid, DateTime date)
        {
            return string.Format("{0}{1}{2}", uid, date.Ticks, RESET_PASSWORD_KEY);
        }
    }
}